package com.zxl.gtion.controller;

import cn.binarywang.wx.miniapp.api.WxMaUserService;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Charsets;
import com.zxl.gtion.config.WxMaConfiguration;
import com.zxl.gtion.entity.User;
import com.zxl.gtion.pojo.WxLoginInfo;
import com.zxl.gtion.service.UserService;
import com.zxl.gtion.shiro.LoginType;
import com.zxl.gtion.shiro.WxMiniToken;
import com.zxl.gtion.util.R;
import com.zxl.gtion.util.ShiroUtils;
import com.zxl.gtion.util.WeChatLoginUtil;
import com.zxl.gtion.vo.WxLoginVo;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * (User)表控制层
 *
 * @author
 * @since 2024-03-06 16:45:24
 */
@RestController
@RequestMapping("user")
@Slf4j
@RequiredArgsConstructor
public class UserController {
    /**
     * 服务对象
     */
    private final UserService userService;

//    @GetMapping("/WxLogin")
//    public R WxLogin(HttpServletRequest request, HttpServletResponse response) throws Exception {
//        response.sendRedirect(WeChatLoginUtil.getUserUathUrl("wxd7485f19621166fe", "https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html"));//(openid和微信回调地址/WxCallback)进行重定向
//        return new R.ok( WeChatLoginUtil.getUserUathUrl(WxOpenLoginConfig.WX_OPEN_APP_ID, WxOpenLoginConfig.WX_OPEN_REDIRECT_URL));
//    }


    @GetMapping("test")
    public R test() throws Exception {
        String userUathUrl = WeChatLoginUtil.getUserUathUrl("wxd7485f19621166fe", "https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html");
        HttpResponse response = HttpRequest
                .get(userUathUrl)
                .method(Method.GET)
                .timeout(5000)
                .charset(Charsets.UTF_8)
                .execute();
        if (response.getStatus() == 200) {
            String body = response.body();
            log.info("body:{}", body);
//                JSONObject jsonObject = JSON.parseObject(body);
        }
        return R.ok(response);
    }

    @ApiOperation("微信小程序用登录")
    @PostMapping("/wxLogin")
    public R<Map<String, Object>> WxLogin(@RequestBody WxLoginVo loginVo) {
        Objects.requireNonNull(loginVo, "code Cannot be null");
        log.info("WxLoginVo:{}", loginVo);

        String appId = "wxd7485f19621166fe";
        String secret = "23de35259573fcebfe3ac59819ec3968";

        try {
            String userUathUrl = WeChatLoginUtil.getUserUathUrl(appId, "https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html");
            HttpResponse response = HttpRequest
                    .get(userUathUrl)
                    .method(Method.GET)
                    .timeout(5000)
                    .charset(Charsets.UTF_8)
                    .execute();
            if (response.getStatus() == 200) {
                String body = response.body();
                log.info("body:{}", body);
//                JSONObject jsonObject = JSON.parseObject(body);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        //  获取微信用户相关信息
        WxMaUserService wxMaUserService
                = WxMaConfiguration.getMaService(appId).getUserService();
//        // 获取微信用户session
//        WxMaJscode2SessionResult sessionInfo = null;
//        try {
//            sessionInfo = userService.getSessionInfo(loginVo.getCode());
//        } catch (WxErrorException e) {
//            e.printStackTrace();
//        }
//        if (!userService.checkUserInfo(sessionInfo.getSessionKey(), loginVo.getRawData(), loginVo.getSignature())) {
//            return R.fail();
//        }

        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + secret + "&js_code=" + loginVo.getCode() + "&grant_type=authorization_code";
        System.out.println("url = " + url);
        String openId = null;
        String sessionKey = null;
        HttpResponse response = HttpRequest
                .get(url)
                .method(Method.GET)
                .timeout(5000)
                .charset(Charsets.UTF_8)
                .execute();
        if (response.getStatus() == 200) {
            String body = response.body();
            log.info("body:{}", body);
            JSONObject jsonObject = JSON.parseObject(body);
            openId = jsonObject.get("openid").toString();
            sessionKey = jsonObject.get("session_key").toString();
//            if (Long.parseLong(jsonObject.get("errcode").toString()) == 0) {
//            } else if (Long.parseLong(jsonObject.get("errcode").toString()) == 40029) {
//                return R.fail("code 无效");
//            } else if (Long.parseLong(jsonObject.get("errcode").toString()) == 45011) {
//                return R.fail("API 调用太频繁，请稍候再试。");
//            } else if (Long.parseLong(jsonObject.get("errcode").toString()) == 40226) {
//                return R.fail("高风险等级用户，小程序登录拦截。");
//            } else {
//                return R.fail("系统繁忙，此时请开发者稍候再试");
//            }
        }
        // 用微信提供的工具获取登录的微信用户基本信息
        WxMaUserInfo userInfo = wxMaUserService.getUserInfo(sessionKey, loginVo.getEncryptedData(), loginVo.getIv());
        log.info("WxMaUserInfo:{}", userInfo);
        log.info("userInfo:{}", userInfo);
        Map<String, Object> map = new HashMap<>();
        try {
            //验证身份和登陆
            // 登录方面用的是shiro
            Subject subject = SecurityUtils.getSubject();
            WxLoginInfo wxLoginInfo = new WxLoginInfo();
            wxLoginInfo.setUserInfo(userInfo);
            wxLoginInfo.setOpenId(openId);
            wxLoginInfo.setLoginType(LoginType.WECHAT_LOGIN);
            subject.login(new WxMiniToken(wxLoginInfo));
        } catch (IncorrectCredentialsException e) {
            return R.fail(1000, e.getMessage());
        } catch (LockedAccountException e) {
            return R.fail(1004, e.getMessage());
        } catch (AuthenticationException e) {
            return R.fail(e.getMessage());
        } catch (Exception e) {
            return R.fail("登录失败");
        }
        map.put("code", 0);
        map.put("msg", "登录成功");
        map.put("token", ShiroUtils.getSession().getId().toString());
        User user = ShiroUtils.getUserInfo();
        map.put("userInfo", user);
        log.info("userInfo: {}", JSON.toJSONString(map));
        return R.ok(map);
    }


}

